from iClouds.header import *
import time, threading
import random, math

tanklist = [
    {
        "name": "Ha-Go",
        "model": "Ha-Go",
        "hp": 10,  # 生命值
        "aggr": [4, 8],  # 攻击力
        "move": 1,  # 移动速度
        "rotate": 10,  # 旋转速度
    },
    {
        "name": "Ke-Ni",
        "model": "Ke-Ni",
        "hp": 10,  # 生命值
        "aggr": [4, 8],  # 攻击力
        "move": 1,  # 移动速度
        "rotate": 10,  # 旋转速度
    },
    {
        "name": "I-Go Ko",
        "model": "I-Go Ko",
        "hp": 20,  # 生命值
        "aggr": [4, 8],  # 攻击力
        "move": 2,  # 移动速度
        "rotate": 20,  # 旋转速度
    },
    {
        "name": "Chi-Ha",
        "model": "Chi-Ha",
        "hp": 20,  # 生命值
        "aggr": [4, 8],  # 攻击力
        "move": 2,  # 移动速度
        "rotate": 20,  # 旋转速度
    },
]


class myREBOT(threading.Thread):
    def __init__(self, room, args=None):
        threading.Thread.__init__(self)
        self.speed = 10
        self.size = [2, 2]
        self.room = room
        self.guid = str(header_has_guuid())
        self.role = {
            "name": "99A主战坦克",
            "model": "99A",
            "hp": 120,  # 生命值
            "aggr": [40, 60],  # 攻击力
            "move": 40,  # 移动速度
            "rotate": 40,  # 旋转速度
        }
        self.status = "fight"
        self.group = 0  # 阵营
        self.health = {
            "hp": [120, 120],
            "aggr": [40, 60],
            "move": [40, 40],
            "rotate": [40, 40],
        }  # 状态
        self.move = {
            "ix": random.choice([0, 20]),
            "iy": 0,
            "iz": 180,
            "speed": 0,
        }  # 位置
        self.look = {"iz": 180, "speed": 0}  # 朝向
        self.maps = room.map
        self.wall = [4, 5, 6, 7, 8]
        self.power = 20
        self.item = {"one": None, "tow": None, "three": None}
        # 加载型号
        self.loadAttr(args)

    def __del__(self):
        try:
            self.room.ai.remove(self)
        except:
            pass

    def stop(self):
        self.status = "death"

    def run(self):
        print(f"{self.guid} 新的Robot...")
        self.alertReport()
        threading.Thread(target=self.movetoPoint).start()
        while self.status == "fight":
            time.sleep(1)
            f = random.choice(range(100))
            if f > 90:
                self.firebePoint()
        self.alertReport()

    def loadAttr(self, args=None):
        """加载坦克"""
        if not args:
            args = tanklist[0]
        # args = {
        #     "name": "Chi-Ha",
        #     "model": "Chi-Ha",
        #     "hp": 20,  # 生命值
        #     "aggr": [4, 8],  # 攻击力
        #     "move": 2,  # 移动速度
        #     "rotate": 20,  # 旋转速度
        # }
        self.role = {
            "name": args["name"],
            "model": args["model"],
            "hp": args["hp"],  # 生命值
            "aggr": args["aggr"],  # 攻击力范围
            "move": args["move"],  # 移动速度
            "rotate": args["rotate"],  # 旋转速度
        }
        self.health = {
            "hp": [args["hp"], args["hp"]],
            "aggr": args["aggr"],  # 攻击力范围 list
            "move": [args["move"], args["move"]],
            "rotate": [args["rotate"], args["rotate"]],
        }  # 状态

    def changeAP(self, scale=1):
        """调整伤害比例"""
        self.health["aggr"][0] = math.ceil(self.role["aggr"][0] * scale)
        self.health["aggr"][1] = math.ceil(self.role["aggr"][1] * scale)

    def alertReport(self):
        """上报信息"""
        data = {
            "act": "gens",
            "guid": self.guid,
            "group": self.group,
            "move": self.move,
            "look": self.look,
            "health": self.health,
            "status": self.status,
        }
        self.room.alertAIring(data)

    def firebePoint(self):
        """开火"""
        data = {
            "act": "fire",
            "guid": self.guid,
            "group": self.group,
            "move": self.move,
            "look": self.look,
            "health": self.health,
            "status": self.status,
        }
        self.room.alertAIring(data)
        # 开线程计算弹道
        threading.Thread(target=self.firetoPoint).start()

    def firetoPoint(self):
        """计算弹道"""
        # 当前位置和火炮角度
        ix, iy, iz = (
            math.ceil(self.move["ix"]),
            math.ceil(self.move["iy"]),
            self.look["iz"],
        )
        while self.status == "fight":
            time.sleep(0.1)
            # 当前弹道路径点
            if iz in [0, 180]:
                if iz == 0:
                    iy -= 1
                    if iy < 0:
                        break
                else:
                    iy += 1
                    if iy >= len(self.room.map["data"]):
                        break
                # a, b = [ix, iy], [ix + 1, iy]
                p = [ix, iy]
            elif iz in [90, 270]:
                if iz == 90:
                    ix += 1
                    if ix >= len(self.room.map["data"][0]):
                        break
                else:
                    ix -= 1
                    if ix < 0:
                        break
                # a, b = [ix, iy], [ix, iy + 1]
                p = [ix, iy]
            else:
                print(f"子弹角度不合法:{iz}")
                break
            # ----------------------------
            # 弹道点 p
            # 是否命中敌方单位
            hit = self.HitThePlayer(p)
            if hit:
                break
            # 是否命中敌方基地或建筑
            hit = self.HitTheTerrain(p)
            if hit:
                break

    def HitThePlayer(self, p):
        """是否命中玩家"""
        # print("AI弹道位置点:", p)
        for tank in self.room.chat:
            # 关闭友军伤害
            if not tank.group:
                continue
            # 计算tank坐标范围
            tx = [tank.move["ix"] + x for x in range(self.size[0])]
            ty = [tank.move["iy"] + y for y in range(self.size[1])]
            farg = [[x, y] for y in ty for x in tx]

            if p in farg:
                fire = random.choice(
                    range(self.health["aggr"][0], self.health["aggr"][1])
                )
                fire2 = tank.health["hp"][0] - fire
                tank.health["hp"] = [fire2, tank.health["hp"][1]]
                if fire2 < 0:
                    tank.status = "death"
                    tank.battle["kill_youjun"] += 1
                    tank.battle["duration"] = time.time() - self.room.ontime
                tank.battle["damage_youjun"] += fire
                data = {
                    "guid": self.guid,
                    "act": "harm",
                    "target": tank.guid,  # 目标GUID
                    "group": tank.group,
                    "health": tank.health,
                    "status": tank.status,
                }
                self.room.alertAIring(data)
                return True
        return False

    def HitTheTerrain(self, a):
        """是否命中建筑"""
        # print("AI弹道位置点:", a)
        if tuple(a) in self.room.flag_range:
            fire = random.choice(range(self.health["aggr"][0], self.health["aggr"][1]))
            self.room.flag -= fire
            data = {
                "guid": self.guid,
                "act": "flag",
                "position": {"ix": a[0], "iy": a[1]},
                "model": self.room.flag,
            }
            self.room.alertAIring(data)
            return True
        if self.room.map["data"][a[1]][a[0]] == 4:
            self.room.map["data"][a[1]][a[0]] = 1
            data = {
                "guid": self.guid,
                "act": "terrain",
                "position": {"ix": a[0], "iy": a[1]},
                "model": 1,
            }
            self.room.alertAIring(data)
            return True
        if self.room.map["data"][a[1]][a[0]] == 5:
            self.room.map["data"][a[1]][a[0]] = 4
            data = {
                "guid": self.guid,
                "act": "terrain",
                "position": {"ix": a[0], "iy": a[1]},
                "model": 4,
            }
            self.room.alertAIring(data)
            return True
        if self.room.map["data"][a[1]][a[0]] == 6:
            self.room.map["data"][a[1]][a[0]] = 5
            data = {
                "guid": self.guid,
                "act": "terrain",
                "position": {"ix": a[0], "iy": a[1]},
                "model": 5,
            }
            self.room.alertAIring(data)
            return True
        return False

    def movetoPoint(self):
        """移动"""
        while self.status == "fight":
            iz = random.choice([0, 90, 180, 270])
            self.move["iz"] = iz
            self.look["iz"] = iz
            self.move["speed"] = self.speed
            self.alertReport()
            while self.status == "fight":
                time.sleep(1)
                # print("AI当前位置:", self.move)
                if iz == 0:
                    self.move["iy"] -= 1 * self.speed
                    if self.move["iy"] <= 0:
                        self.move["iy"] = 0
                        break
                    if (
                        self.room.map["data"][math.ceil(self.move["iy"]) - 1][
                            math.ceil(self.move["ix"])
                        ]
                        in self.wall
                    ):
                        break
                    if (
                        self.room.map["data"][math.ceil(self.move["iy"]) - 1][
                            math.ceil(self.move["ix"]) + 1
                        ]
                        in self.wall
                    ):
                        break

                elif iz == 90:
                    self.move["ix"] += 1 * self.speed
                    if self.move["ix"] >= len(self.room.map["data"][0]) - self.size[0]:
                        self.move["ix"] = len(self.room.map["data"][0]) - self.size[0]
                        break
                    if (
                        self.room.map["data"][math.ceil(self.move["iy"])][
                            math.ceil(self.move["ix"]) + 1
                        ]
                        in self.wall
                    ):
                        break
                    if (
                        self.room.map["data"][math.ceil(self.move["iy"]) + 1][
                            math.ceil(self.move["ix"]) + 1
                        ]
                        in self.wall
                    ):
                        break
                elif iz == 180:
                    self.move["iy"] += 1 * self.speed
                    if self.move["iy"] >= len(self.room.map["data"]) - self.size[1]:
                        self.move["iy"] = len(self.room.map["data"]) - self.size[1]
                        break
                    if (
                        self.room.map["data"][math.ceil(self.move["iy"]) + 1][
                            math.ceil(self.move["ix"])
                        ]
                        in self.wall
                    ):
                        break
                    if (
                        self.room.map["data"][math.ceil(self.move["iy"]) + 1][
                            math.ceil(self.move["ix"]) + 1
                        ]
                        in self.wall
                    ):
                        break
                elif iz == 270:
                    self.move["ix"] -= 1 * self.speed
                    if self.move["ix"] <= 0:
                        self.move["ix"] = 0
                        break
                    if (
                        self.room.map["data"][math.ceil(self.move["iy"])][
                            math.ceil(self.move["ix"]) - 1
                        ]
                        in self.wall
                    ):
                        break
                    if (
                        self.room.map["data"][math.ceil(self.move["iy"]) + 1][
                            math.ceil(self.move["ix"]) - 1
                        ]
                        in self.wall
                    ):
                        break
                else:
                    pass
                # print(self.move["ix"], self.move["iy"])
